package com.fangcang.mapping.service.impl;

import com.alibaba.fastjson.JSON;
import com.fangcang.common.IncrementDTO;
import com.fangcang.common.IncrementType;
import com.fangcang.common.PaginationSupportDTO;
import com.fangcang.common.ResponseDTO;
import com.fangcang.common.config.OtaConfig;
import com.fangcang.common.constant.InitData;
import com.fangcang.common.enums.ErrorCodeEnum;
import com.fangcang.common.util.DateUtil;
import com.fangcang.common.util.HttpClientUtil;
import com.fangcang.common.util.StringUtil;
import com.fangcang.hotelinfo.domain.RoomTypeDO;
import com.fangcang.hotelinfo.mapper.RoomTypeMapper;
import com.fangcang.mapping.mapper.RatePlanMappingMapper;
import com.fangcang.mapping.request.feizhu.*;
import com.fangcang.mapping.response.QueryRoomTypeAndRpListResponse;
import com.fangcang.mapping.response.feizhu.*;
import com.fangcang.mapping.service.FeizhuMappingService;
import com.fangcang.product.dto.RestrictDTO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author chihping
 * @Description TODO
 * @date 19-2-19 下午5:42
 */
@Service
@Slf4j
public class FeizhuMappingServiceImpl implements FeizhuMappingService {

    @Autowired
    private RatePlanMappingMapper ratePlanMappingMapper;

    @Autowired
    private OtaConfig otaConfig;

    @Autowired
    private RoomTypeMapper roomTypeMapper;

    @Override
    public ResponseDTO<PaginationSupportDTO<QueryFeizhuHotelMappingResponse>> queryFeizhuHotelListForPage(QueryFeizhuHotelMappingRequest queryFeizhuHotelMappingRequest) {

        ResponseDTO responseDTO = new ResponseDTO(ErrorCodeEnum.SUCCESS);

        //分页查询
        PageHelper.startPage(queryFeizhuHotelMappingRequest.getCurrentPage(), queryFeizhuHotelMappingRequest.getPageSize());
        List<QueryFeizhuHotelMappingResponse> feizhuHotelMappingResponseList = ratePlanMappingMapper.queryFeizhuHotelListForPage(queryFeizhuHotelMappingRequest);
        PageInfo<QueryFeizhuHotelMappingResponse> pageInfo = new PageInfo<>(feizhuHotelMappingResponseList);
        PaginationSupportDTO paginationSupportDTO = new PaginationSupportDTO();
        paginationSupportDTO.setTotalCount(pageInfo.getTotal());
        paginationSupportDTO.setTotalPage(pageInfo.getPages());
        paginationSupportDTO.setCurrentPage(pageInfo.getPageNum());
        paginationSupportDTO.setPageSize(pageInfo.getPageSize());
        paginationSupportDTO.setItemList(feizhuHotelMappingResponseList);

        responseDTO.setModel(paginationSupportDTO);
        return responseDTO;
    }

    @Override
    public ResponseDTO<AddHotelToFeizhuResponse> addHotelToFeizhu(AddHotelToFeizhuRequest addHotelToFeizhuRequest) {

        ResponseDTO<AddHotelToFeizhuResponse> responseDTO = new ResponseDTO(ErrorCodeEnum.SUCCESS);
        QueryFeizhuHotelMappingRequest queryFeizhuHotelMappingRequest = new QueryFeizhuHotelMappingRequest();
        queryFeizhuHotelMappingRequest.setHotelId(Long.valueOf(addHotelToFeizhuRequest.getHotelId()));
        List<QueryFeizhuHotelMappingResponse> feizhuHotelMappingResponseList = ratePlanMappingMapper.queryFeizhuHotelListForPage(queryFeizhuHotelMappingRequest);

        if (CollectionUtils.isEmpty(feizhuHotelMappingResponseList)){
            log.error("推送酒店到飞猪时未查到该酒店，请求参数：{}", JSON.toJSONString(addHotelToFeizhuRequest));
            responseDTO.setErrorCode(ErrorCodeEnum.MAPPING_HOTEL_NOT_FOUND);
            return responseDTO;
        }

        QueryFeizhuHotelMappingResponse hotelMappingResponse = feizhuHotelMappingResponseList.get(0);
        addHotelToFeizhuRequest.setAddress(hotelMappingResponse.getAddress());
        addHotelToFeizhuRequest.setCityCode(hotelMappingResponse.getCityCode());
        addHotelToFeizhuRequest.setTel(hotelMappingResponse.getPhone());
        addHotelToFeizhuRequest.setName(hotelMappingResponse.getHotelName());

        responseDTO = invokeFliggyServer(addHotelToFeizhuRequest,otaConfig.getAddHotel());
        log.info("调用fliggy-server的推送酒店接口.请求：{}，返回：{}",JSON.toJSONString(addHotelToFeizhuRequest), JSON.toJSONString(responseDTO));
        return responseDTO;
    }

    @Override
    public ResponseDTO<GetFeizhuHotelResponse> getFeizhuHotel(GetFeizhuHotelRequest getFeizhuHotelRequest) {

        ResponseDTO responseDTO = ResponseDTO.successInstance();
        if (null == getFeizhuHotelRequest || null == getFeizhuHotelRequest.getHotelId()){
            log.error("调用fliggy-server查询酒店时，参数为空");
            responseDTO.setErrorCode(ErrorCodeEnum.INVALID_INPUTPARAM);
            return responseDTO;
        }

        responseDTO = invokeFliggyServer(getFeizhuHotelRequest,otaConfig.getGetHotel());
        log.info("调用fliggy-server的查询酒店接口.请求：{}，返回：{}",JSON.toJSONString(getFeizhuHotelRequest), JSON.toJSONString(responseDTO));
        return responseDTO;
    }

    @Override
    public ResponseDTO<FeizhuHotelResponse> queryRoomTypeAndPricePlanList(QueryRoomTypeAndRpListRequest queryRoomTypeAndRpListRequest) {

        ResponseDTO responseDTO = ResponseDTO.successInstance();
        List<QueryRoomTypeAndRpListResponse> ratePlanList = ratePlanMappingMapper.queryRoomTypeAndPricePlanList(queryRoomTypeAndRpListRequest);
        if (CollectionUtils.isEmpty(ratePlanList)){
            log.info("没有查到价格计划列表，请求参数：{}",JSON.toJSONString(queryRoomTypeAndRpListRequest));
            return responseDTO;
        }

        QueryRoomTypeAndRpListResponse tempResponse = ratePlanList.get(0);
        FeizhuHotelResponse feizhuHotelResponse = new FeizhuHotelResponse();
        feizhuHotelResponse.setHotelId(tempResponse.getHotelId());
        feizhuHotelResponse.setHotelName(tempResponse.getHotelName());

        //列表型数据，转换成树形结构
        Map<Integer, FeizhuRoomTypeResponse> roomTypeMap = new HashMap<>();
        FeizhuRoomTypeResponse roomTypeResponse = null;
        FeizhuRatePlanResponse ratePlanResponse = null;
        for (QueryRoomTypeAndRpListResponse temp : ratePlanList){

            ratePlanResponse = new FeizhuRatePlanResponse();
            ratePlanResponse.setPricePlanId(temp.getPricePlanId());
            ratePlanResponse.setPricePlanName(temp.getPricePlanName());
            ratePlanResponse.setRpid(temp.getRpid());

            if (roomTypeMap.containsKey(temp.getRoomTypeId())){
                roomTypeMap.get(temp.getRoomTypeId()).getPricePlanList().add(ratePlanResponse);
            }else{
                roomTypeResponse = new FeizhuRoomTypeResponse();
                roomTypeResponse.setRoomTypeId(temp.getRoomTypeId());
                roomTypeResponse.setRoomTypeName(temp.getRoomTypeName());
                roomTypeResponse.setRid(temp.getRid());
                roomTypeResponse.setName(temp.getFeizhuRoomName());
                roomTypeResponse.getPricePlanList().add(ratePlanResponse);

                feizhuHotelResponse.getRoomTypeList().add(roomTypeResponse);

                roomTypeMap.put(temp.getRoomTypeId(),roomTypeResponse);
            }
        }

        responseDTO.setModel(feizhuHotelResponse);

        return responseDTO;
    }

    @Override
    public ResponseDTO<List<ShopInfo>> queryFeizhuShop(String merchantCode) {
        ResponseDTO responseDTO = ResponseDTO.successInstance();
        List<ShopInfo> shopInfoList = InitData.merchantShopMap.get(merchantCode);
        if (CollectionUtils.isEmpty(shopInfoList)){
            //查询数据库，并放入内存中
            ShopInfo queryInfo = new ShopInfo();
            queryInfo.setMerchantCode(merchantCode);
            shopInfoList = ratePlanMappingMapper.queryFeizhuShop(queryInfo);

            if (CollectionUtils.isEmpty(shopInfoList)){
                log.error("{}没有配置店铺信息。",merchantCode);
                responseDTO.setErrorCode(ErrorCodeEnum.MAPPING_SHOP_NOT_FOUND);
                responseDTO.setResult(1);
            } else {
                InitData.merchantShopMap.put(merchantCode,shopInfoList);
            }
        }
        responseDTO.setModel(shopInfoList);
        return responseDTO;
    }

    @Override
    public void initFeizhuShopInfo() {
        //对应InitData.merchantShopMap
        Map<String,List<ShopInfo>> shopInfoMap = new HashMap<>();

        //对应InitData.merchantShopChanneCodeMap
        Map<String,String> shopChannelMap = new HashMap<>();

        //对应InitData.merchantChannelCodeShopMap
        Map<String,String> merchantChannelCodeShopMap = new HashMap<>();

        ShopInfo queryInfo = new ShopInfo();
        List<ShopInfo> shopInfoList = ratePlanMappingMapper.queryFeizhuShop(queryInfo);
        for (ShopInfo shopInfo : shopInfoList){
            if (shopInfoMap.containsKey(shopInfo.getMerchantCode())){
                shopInfoMap.get(shopInfo.getMerchantCode()).add(shopInfo);
            }else {
                List<ShopInfo> shopInfoList1 = new ArrayList<>();
                shopInfoList1.add(shopInfo);
                shopInfoMap.put(shopInfo.getMerchantCode(),shopInfoList);
            }

            shopChannelMap.put(shopInfo.getMerchantCode()+"-"+shopInfo.getShopId(),shopInfo.getChannelCode());
            merchantChannelCodeShopMap.put(shopInfo.getMerchantCode()+"-"+shopInfo.getChannelCode(),shopInfo.getShopId());
        }

        InitData.merchantShopMap = shopInfoMap;
        InitData.merchantShopChanneCodeMap = shopChannelMap;
        InitData.merchantChannelCodeShopMap = merchantChannelCodeShopMap;
    }

    @Override
    public ResponseDTO<AddRoomTypeToFeizhuResponse> addRoomTypeToFeizhu(AddRoomTypeToFeizhuRequest addRoomTypeToFeizhuRequest) {
        //从基础信息表中查出房型的基本信息：名称、床型等。
        ResponseDTO responseDTO = ResponseDTO.successInstance();

        RoomTypeDO queryDO = new RoomTypeDO();
        queryDO.setRoomTypeId(addRoomTypeToFeizhuRequest.getRoomTypeId());
        RoomTypeDO roomTypeDO = roomTypeMapper.queryRoomTypeInfoById(queryDO);
        if (null == roomTypeDO ){
            log.error("新增房型失败：系统无此房型，请求参数：{}",JSON.toJSONString(addRoomTypeToFeizhuRequest));
            responseDTO = new ResponseDTO(ErrorCodeEnum.MAPPING_ROOMTYPE_NOT_FOUND);
            return responseDTO;
        }

        addRoomTypeToFeizhuRequest.setName(roomTypeDO.getRoomTypeName());
        addRoomTypeToFeizhuRequest.setHotelId(roomTypeDO.getHotelId());
        if (StringUtil.isValidString(roomTypeDO.getBedType())){
            List<Integer> bedTypeList = new ArrayList<>();
            String[] bedTypeArray = roomTypeDO.getBedType().split(",");
            for (String bedTypeStr : bedTypeArray){
                bedTypeList.add(Integer.valueOf(bedTypeStr));
            }
            addRoomTypeToFeizhuRequest.setBedTypeList(bedTypeList);
        }

        responseDTO = invokeFliggyServer(addRoomTypeToFeizhuRequest, otaConfig.getAddRoomType());
        log.info("调用fliggy-server的新增房型接口.请求：{}，返回：{}",JSON.toJSONString(addRoomTypeToFeizhuRequest), JSON.toJSONString(responseDTO));
        return responseDTO;
    }

    @Override
    public ResponseDTO<GetFeizhuRoomTypeResponse> getFeizhuRoomType(GetFeizhuRoomTypeRequest getFeizhuRoomTypeRequest) {

        ResponseDTO responseDTO = invokeFliggyServer(getFeizhuRoomTypeRequest, otaConfig.getGetRoomType());
        log.info("调用fliggy-server的查询房型接口.请求：{}，返回：{}",JSON.toJSONString(getFeizhuRoomTypeRequest), JSON.toJSONString(responseDTO));
        return responseDTO;
    }

    @Override
    public ResponseDTO<AddRatePlanToFeizhuResponse> addRatePlanToFeizhu(AddRatePlanToFeizhuResquest addRatePlanToFeizhuResquest) {
        ResponseDTO responseDTO = ResponseDTO.successInstance();
        QueryRoomTypeAndRpListRequest queryRoomTypeAndRpListRequest = new QueryRoomTypeAndRpListRequest();
        queryRoomTypeAndRpListRequest.setShopId(addRatePlanToFeizhuResquest.getShopId());
        queryRoomTypeAndRpListRequest.setMerchantCode(addRatePlanToFeizhuResquest.getMerchantCode());
        queryRoomTypeAndRpListRequest.getPricePlanIdList().add(addRatePlanToFeizhuResquest.getPricePlanId().intValue());
        List<QueryRoomTypeAndRpListResponse> ratePlanList = ratePlanMappingMapper.queryRoomTypeAndPricePlanList(queryRoomTypeAndRpListRequest);
        if (CollectionUtils.isEmpty(ratePlanList)){
            log.error("没有查到价格计划，请求参数：{}",JSON.toJSONString(addRatePlanToFeizhuResquest));
            responseDTO.setErrorCode(ErrorCodeEnum.MAPPING_PRICEPLAN_NOT_FOUND);
            return responseDTO;
        }

        QueryRoomTypeAndRpListResponse pricePlan = ratePlanList.get(0);

        if (StringUtil.isValidString(pricePlan.getRpid())){
            log.error("此价格计划已经推送到飞猪了,无需再推送，飞猪价格计划ID={}，请求参数：{}",pricePlan.getRpid(), JSON.toJSONString(addRatePlanToFeizhuResquest));
            responseDTO.setErrorCode(ErrorCodeEnum.MAPPING_PRICEPLAN_REAPREAT_PUSH);
            return responseDTO;
        }

        addRatePlanToFeizhuResquest.setBreakFastType(pricePlan.getBreakfastType());
        addRatePlanToFeizhuResquest.setPricePlanName(pricePlan.getPricePlanName());
        addRatePlanToFeizhuResquest.setPayMethod(pricePlan.getPayMethod());
        RestrictDTO restrictDTO = new RestrictDTO();
        restrictDTO.setCancelType(1);//一经预定不可取消
        addRatePlanToFeizhuResquest.setRestrictDTO(restrictDTO);

        addRatePlanToFeizhuResquest.setHotelId(Long.valueOf(pricePlan.getHotelId()));
        if (StringUtil.isValidString(pricePlan.getHid())){
            addRatePlanToFeizhuResquest.setHid(Long.valueOf(pricePlan.getHid()));
        }
        if (StringUtil.isValidString(pricePlan.getRid())){
            addRatePlanToFeizhuResquest.setRid(Long.valueOf(pricePlan.getRid()));
        }
        addRatePlanToFeizhuResquest.setRoomTypeId(Long.valueOf(pricePlan.getRoomTypeId()));

        responseDTO = invokeFliggyServer(addRatePlanToFeizhuResquest, otaConfig.getAddRatePlan());
        log.info("调用fliggy-server的新增价格计划接口.请求：{}，返回：{}",JSON.toJSONString(addRatePlanToFeizhuResquest), JSON.toJSONString(responseDTO));
        return responseDTO;
    }

    @Override
    public ResponseDTO<DelRatePlanToFeizhuResponse> delRatePlanToFeizhu(DelRatePlanToFeizhuResquest delRatePlanToFeizhuResquest) {
        ResponseDTO responseDTO = invokeFliggyServer(delRatePlanToFeizhuResquest, otaConfig.getDelRatePlan());
        log.info("调用fliggy-server的新删除格计划接口.请求：{}，返回：{}",JSON.toJSONString(delRatePlanToFeizhuResquest), JSON.toJSONString(responseDTO));
        return responseDTO;
    }

    @Override
    public ResponseDTO<SyncRateAndQuotaToFeizhuResponse> syncRateAndQuotaToFeizhu(SyncRateAndQuotaToFeizhuResquest syncRateAndQuotaToFeizhuResquest) {

        //转换成增量一样的参数，调用增量的方法
        List<IncrementDTO> incrementDTOList = new ArrayList<>();
        IncrementDTO incrementDTO = new IncrementDTO();
        incrementDTO.setStartDate(DateUtil.dateToString(DateUtil.getCurrentDate()));
        //默认推送30天的数据过去
        incrementDTO.setEndDate(DateUtil.dateToString(DateUtil.getDate(DateUtil.getCurrentDate(),30,0)));
        incrementDTO.setMRatePlanId(syncRateAndQuotaToFeizhuResquest.getPricePlanId());
        incrementDTOList.add(incrementDTO);
        syncRateAndQuotaToFeizhuResquest.setIncrementDTOList(incrementDTOList);
        syncRateAndQuotaToFeizhuResquest.setIncrementType(IncrementType.instant().andRoomStatus().andPrice());

        ResponseDTO responseDTO = invokeFliggyServer(syncRateAndQuotaToFeizhuResquest, otaConfig.getPriceAndRoomStatus());
        log.info("调用fliggy-server的同步价格和房态接口.请求：{}，返回：{}", JSON.toJSONString(syncRateAndQuotaToFeizhuResquest), JSON.toJSONString(responseDTO));
        return responseDTO;
    }


    private String getRemoteUrl(String channelCode,String methodName) {
        //根据渠道获取对应的应用，再拼接上对应的方法名称
        return otaConfig.getUrlMap().get(channelCode) + methodName;
    }

    private String getChannelCode(FeizhuBaseRequest addHotelToFeizhuRequest) {
        String merchantShopkey = addHotelToFeizhuRequest.getMerchantCode()+"-"+addHotelToFeizhuRequest.getShopId();
        String channelCode = InitData.merchantShopChanneCodeMap.get(merchantShopkey);
        return channelCode;
    }


    private ResponseDTO invokeFliggyServer(FeizhuBaseRequest feizhuBaseRequest, String methodName) {
        ResponseDTO responseDTO = new ResponseDTO(ErrorCodeEnum.SUCCESS);
        //调用fliggy-server
        String channelCode = getChannelCode(feizhuBaseRequest);
        String url = getRemoteUrl(channelCode,methodName);
        String requestParam = JSON.toJSONString(feizhuBaseRequest);
        String responseStr = null;
        try {
            responseStr = HttpClientUtil.postJson(url, requestParam);
        } catch (IOException e) {
            log.error("调用fliggy-server时IO异常。URL:{}。请求参数：{}。返回参数：{}。",url,requestParam,responseStr,e);
            responseDTO.setErrorCode(ErrorCodeEnum.SYSTEM_EXCEPTION);
            return responseDTO;
        }
        responseDTO = JSON.parseObject(responseStr,ResponseDTO.class);

        return responseDTO;
    }
}
